﻿//Copyright 2008 Kristian Gundry And Rune Juhl-Petersen
//This file is part of Plain.

//Plain is free software: you can redistribute it and/or modify
//it under the terms of the GNU Lesser General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//any later version.

//Plain is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU Lesser General Public License for more details.

//You should have received a copy of the GNU Lesser General Public License
//along with Plain.  If not, see <http://www.gnu.org/licenses/>.
using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI;
using Plain;
using Plain.Search;
using System.Reflection;
using System.IO;

using System.Web.UI.WebControls;
using System.Web;
using System.Security.Permissions;
using System.ComponentModel;
using System.Windows.Markup;
using Plain.Utilities;
using System.Linq;

namespace Plain.Web
{
   /// <summary>
   /// 
   /// </summary>
        [ParseChildren(true)]
    public class PlainDataSource : DataSourceControl,INamingContainer{
        protected override DataSourceView GetView(string viewName){
   
           
                
            PlainDataView view = new PlainDataView(this,"bla");
            view.type=System.Type.GetType(type);
            Path = path;
            IDictionary<string, object> dic = new Dictionary<string, object>();

            if (Parameters != null) {
                foreach (Parameter par in Parameters) {
                    if (par is FormParameter) {
                        FormParameter fPar = par as FormParameter;
                        if (fPar != null) {
                            string val = HttpContext.Current.Request.Form[fPar.FormField];
                            if (val != null) {
                                dic.Add(par.Name, val);
                            } else {
                                dic.Add(par.Name, par.DefaultValue);
                            }
                        }
                    } else if (par is QueryStringParameter) {
                        QueryStringParameter q = (QueryStringParameter)par;
                        string val = HttpContext.Current.Request[q.QueryStringField];
                        if (!string.IsNullOrEmpty(val)) {
                            dic.Add(q.Name, val);
                        } else if (!string.IsNullOrEmpty(q.DefaultValue)) {
                            dic.Add(q.Name, q.DefaultValue);
                        }
                    } else if (par is ControlParameter) {
                        ControlParameter cp = (ControlParameter)par;
                        Control c = Page.findControl<Control, Control>().First(x => x.ID == cp.ControlID);
                        object o = c.GetType().GetProperty(cp.PropertyName).GetValue(c, null);
                        if (o != null) {
                            dic.Add(cp.Name, o);
                        } else if (cp.DefaultValue != null) {
                            dic.Add(cp.Name, cp.DefaultValue);
                        }

                    } else if (par is CookieParameter) {
                        CookieParameter cp = (CookieParameter)par;
                        HttpCookie cookie = HttpContext.Current.Request.Cookies[cp.CookieName];
                        if (cookie != null) {
                            dic.Add(cp.Name, cookie.Values);
                        } else if (cp.DefaultValue != null) {
                            dic.Add(cp.Name, cp.DefaultValue);
                        }
                    } else if (par is SessionParameter) {
                        SessionParameter sp = (SessionParameter)par;
                        object val = HttpContext.Current.Session[sp.SessionField];
                        if (val != null) {
                            dic.Add(par.Name, val);
                        } else {
                            dic.Add(par.Name, par.DefaultValue);
                        }

                    } else if (par is ProfileParameter) {
                        ProfileParameter pp = (ProfileParameter)par;

                        object val = HttpContext.Current.Profile[pp.PropertyName];

                        if (val != null) {
                            dic.Add(par.Name, val);
                        } else {
                            dic.Add(par.Name, par.DefaultValue);
                        }
                    } else if (par is Parameter) {
                        dic.Add(par.Name, par.DefaultValue);
                    }
                }
            }
            view.dic = dic;
            return view;
        }

        private Control FindControlRecursive(Control c,string name) {
            if (c.ID == name) {
                return c;
            } else {
                foreach (Control subC in c.Controls) {
                    Control c2 = FindControlRecursive(subC, name);
                    if (c2 != null) {
                        return c2;
                    }
                }
            }
            return null;

        }

        private string type;
        public string Type {
            get { return type; }
            set { type = value; }
        }
            [Browsable(true)]
            [Category("Query")]
        public string SortParameterName { get; set; }

        private string path=null;
        private ParameterCollection parameters;
            [Browsable(true)]
        [Category("Query")]
        [PersistenceModeAttribute(PersistenceMode.InnerProperty)]        
        public ParameterCollection Parameters {
            get {
                return parameters;
            }
            set {
                parameters = value;
            }
        }
        public string Path {  get; set; }
        public bool CanSort { get { return true; } }
        public bool CanPage { get { return true; } }

    }
    internal class PlainDataView : DataSourceView{
        public Type type;
        public Criteria criteria;
        public string path;
        public IDictionary<string, object> dic;
        protected override System.Collections.IEnumerable ExecuteSelect(DataSourceSelectArguments arguments){
            
            //return PlainApplication.Config.DaoFactory.GetDao<int,type>().Search(null);
            Type dft = PlainApplication.Config.DaoFactory.GetType();
            MethodInfo[] methods = dft.GetMethods();
            MethodInfo g = null;
            object value = null;

            foreach (MethodInfo m in methods)
            {
                if (m.Name == "GetDao" && m.IsGenericMethod)
                {
                    g = m.MakeGenericMethod(type, type.GetProperty("Id").PropertyType);
                    break;
                }
            }object Dao = null;

            

            if (g != null)
                Dao = g.Invoke(PlainApplication.Config.DaoFactory, null);
            
            Type dt = Dao.GetType();
            MethodInfo dm = dt.GetMethod("Search",new Type[]{typeof(Criteria) , typeof(IDictionary<string,object>),typeof(long),typeof(long),typeof(string)});
            Criteria crit = null;
            if (!string.IsNullOrEmpty(path)) {
                FileStream stream = new FileStream(path, FileMode.Open);
                XamlReader reader = new XamlReader();
                crit = (Criteria)XamlReader.Load(stream);
            }
            if (arguments.RetrieveTotalRowCount) {
                MethodInfo getCount = dt.GetMethod("GetCount");
                object vla =getCount.Invoke(Dao, new object[] { crit,dic});
                arguments.TotalRowCount=(int)vla;

            }

            value = dm.Invoke(Dao, new object[] { crit,dic,arguments.StartRowIndex,arguments.MaximumRows,arguments.SortExpression });
            return (System.Collections.IEnumerable)value;
        }
        public override bool CanSort {
            get {
                return true;
            }
        }
        public override bool CanPage {
            get {
                return true;
            }
        }
        public override bool CanRetrieveTotalRowCount {
            get {
                return true;
            }
        }
        public PlainDataView(IDataSource owner, string name): base(owner, "bla"){
            
        }
        PropertyIdentifier title = new PropertyIdentifier("Title");
        PropertyIdentifier content = new PropertyIdentifier("Content");
        PropertyIdentifier Kategori = new PropertyIdentifier("Category.Name");
        PropertyIdentifier Subarticle = new PropertyIdentifier("SubArticle.Title");
        PropertyIdentifier SubarticleCat = new PropertyIdentifier("SubArticle.Category.Name");

        

        public Criteria Criteria{
            get{
                if (string.IsNullOrEmpty("wef")){
                    return null;
                }
                else
                {
                    return (title.Contains("test") | content.Contains("test")) & title != "test" | Kategori.Contains("test");
                    //return SubarticleCat.Contains(SearchField.Text);
                }
            }
        }
    }

}
